/**
 * describe:
 *
 * @author huxingjie
 * @date 2020/10/19
 * @since 5.0
 *//*

package com.sensetime.iva.whale.bdp.api.common.utils;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.sensetime.iva.whale.bdp.api.client.request.vo.LabelExpression;
import com.sensetime.iva.whale.bdp.api.client.request.vo.LabelFilter;
import com.sensetime.iva.whale.bdp.api.client.request.vo.Printable;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;
import java.util.concurrent.atomic.AtomicBoolean;

*/
/**
 * Copyright (C), 2019, Sensetime Tech. Co., Ltd.
 *
 * @Name: RpnUtil
 * @Since: 4.0
 * @Version: v1.0
 * @Date: 2020/7/31 9:07
 * @Author: zhouguanbao@sensetime.com
 * @Description: 标签工具类
 **//*

public class RpnUtil {

    public static final String LABEL_FILTER = "labelids";

    */
/**
     * @Author zhouguanbao@sensetime.com
     * @Description 中序表达式转后序表达式
     * @Date 2020/8/7 9:32
     * @Param 中序表达式
     * @Return 后序表达式
     **//*

    public static List<Printable> middleToLast(LabelExpression labelExpression) {
        LabelExpression expression = labelExpression;
        Stack<Printable> operators = new Stack<>();
        List<Printable> output = Lists.newLinkedList();

        while (expression != null) {

            if (expression.getBrackets() != null && LabelExpression.Brackets.LEFT.equals(expression.getBrackets())) {
                operators.push(LabelExpression.Brackets.LEFT);
            }

            if (null != expression.getLabelFilter()) {
                output.add(expression.getLabelFilter());
            }

            if (LabelExpression.Brackets.RIGHT.toString().equals(expression.getBrackets())) {
                Printable o;
                while (!operators.empty()) {
                    o = operators.pop();
                    if (!(o.equals(LabelExpression.Brackets.LEFT))) {
                        output.add(o);
                    } else {
                        break;
                    }
                }
            }

            LabelExpression.LabelOperator opator = LabelExpression.LabelOperator.getByOprator(expression.getLabelOperator());
            if (null != opator) {
                operators.push(opator);
            }

            expression = expression.getExpression();
        }

        Printable o;
        while (!operators.empty()) {
            o = operators.pop();
            output.add(o);
        }

        output.stream().forEach(Printable::print);

        return output;

    }

    */
/**
     * @Author zhouguanbao@sensetime.com
     * @Description 从表达式中提取标签项
     * @Date 2020/8/7 15:00
     * @Param
     * @Return
     **//*

    public static List<LabelFilter> extractLabel(LabelExpression labelExpression) {
        LabelExpression expression = labelExpression;
        List<LabelFilter> labelFilters = Lists.newArrayList();

        while (expression != null) {
            if (null != expression.getLabelFilter()) {
                labelFilters.add(expression.getLabelFilter());
            }

            expression = expression.getExpression();
        }

        return labelFilters;
    }

    public static <T> Collection<T> minus(Collection<T> source, Collection<T> delete) {
        Collection<T> ret = Lists.newArrayList(source);
        Iterator<T> iterator = ret.iterator();
        while (iterator.hasNext()) {
            if (delete.contains(iterator.next())) {
                iterator.remove();
            }
        }

        return ret;
    }

    */
/**
     * @Author zhouguanbao@sensetime.com
     * @Description 后序表达式转ES查询
     * @Date 2020/8/7 9:34
     * @Param 后序表达式
     * @Return es查询
     **//*

    public static QueryBuilder translateExpToQuery(List<Printable> rpnExp) {

        Stack<QueryBuilder> queryBuilders = new Stack<>();

        AtomicBoolean trigger = new AtomicBoolean(false);

        rpnExp.forEach(e -> {
            if (e instanceof LabelFilter) {
                QueryBuilder queryBuilder = QueryBuilders.termQuery(LABEL_FILTER, composite((LabelFilter) e));
                queryBuilders.push(queryBuilder);
            }
            if (e instanceof LabelExpression.LabelOperator) {
                if (!trigger.get()) {

                    QueryBuilder queryBuilder1 = queryBuilders.pop();
                    QueryBuilder queryBuilder2 = queryBuilders.pop();

                    BoolQueryBuilder tmpQuery = QueryBuilders.boolQuery();
                    if (e.equals(LabelExpression.LabelOperator.OR)) {
                        tmpQuery.should(queryBuilder1);
                        tmpQuery.should(queryBuilder2);

                    } else {
                        tmpQuery.filter(queryBuilder1);
                        tmpQuery.filter(queryBuilder2);
                    }

                    queryBuilders.push(tmpQuery);

                    trigger.set(true);
                } else {
                    QueryBuilder queryBuilder1 = queryBuilders.pop();
                    QueryBuilder queryBuilder2 = queryBuilders.pop();

                    BoolQueryBuilder tmpQuery = QueryBuilders.boolQuery();

                    if (e.equals(LabelExpression.LabelOperator.AND)) {
                        tmpQuery.filter(queryBuilder1).filter(queryBuilder2);
                    } else {
                        tmpQuery.should(queryBuilder1).should(queryBuilder2);
                    }

                    queryBuilders.push(tmpQuery);
                }
            }
        });

        return queryBuilders.pop();

    }

    public static String composite(LabelFilter labelFilter) {
        return labelFilter.getCategoryId() + "." + labelFilter.getLabelId();
    }

    */
/**
     * 中序转后序
     *//*

    public static List<String> midToLast(List<String> formulaList) {
        Stack<String> operators = new Stack<>();
        List<String> result = Lists.newArrayList();
        for (String formula : formulaList) {
            if (formula.contains(".")) {
                result.add(formula);
            } else if ("(".equals(formula)) {
                operators.push(formula);
            } else if (")".equals(formula)) {
                while (!"(".equals(operators.peek())) {
                    result.add(operators.pop());
                }
                operators.pop();
            } else {
                while (operators.size() != 0 && getLevel(operators.peek()) >= getLevel(formula)) {
                    result.add(operators.pop());
                }
                operators.push(formula);
            }
        }
        while (operators.size() != 0) {
            result.add(operators.pop());
        }
        return result;
    }

    */
/**
     * 运算符优先级
     *//*

    private static int getLevel(String operator) {
        if (operator == null || operator.length() == 0) {
            return 0;
        }
        switch (operator) {
            case "(":
                return 0;
            case "or":
            case "and":
                return 1;
            default:
                return -1;
        }
    }


    public static void main(String[] args) {
        LabelExpression expression = new LabelExpression();
        LabelFilter labelFilter1 = new LabelFilter();
        labelFilter1.setCategoryId("1");
        labelFilter1.setLabelId("2");
        expression.setLabelFilter(labelFilter1);
        expression.beginBrackets();
        expression.setLabelOperator(LabelExpression.LabelOperator.OR.toString());


        LabelExpression expression1 = new LabelExpression();
        LabelFilter labelFilter2 = new LabelFilter();
        labelFilter2.setCategoryId("1");
        labelFilter2.setLabelId("3");
        expression1.setLabelFilter(labelFilter2);
        expression.setExpression(expression1);
        expression1.endBrackets();
        expression1.setLabelOperator(LabelExpression.LabelOperator.AND_NOT.toString());


        LabelExpression expression2 = new LabelExpression();
        LabelFilter labelFilter3 = new LabelFilter();
        labelFilter3.setCategoryId("2");
        labelFilter3.setLabelId("3");
        expression2.setLabelFilter(labelFilter3);
        expression2.beginBrackets();
        expression2.setLabelOperator(LabelExpression.LabelOperator.AND.toString());

        LabelExpression expression3 = new LabelExpression();
        LabelFilter labelFilter4 = new LabelFilter();
        labelFilter4.setCategoryId("3");
        labelFilter4.setLabelId("1");
        expression3.setLabelFilter(labelFilter4);

        expression1.setExpression(expression2);

        expression2.setExpression(expression3);

        expression3.endBrackets();

        LabelExpression expression4 = new LabelExpression();


        expression4.setExpression(expression);




        expression4.print();
        System.out.println();
        System.out.println(expression4.getQuerySql("labelids"));


        System.out.println(JSON.toJSONString(expression4));

        List<Printable> out = middleToLast(expression4);
//
//        QueryBuilder boolQueryBuilder = translateExpToQuery(out);
//
//        System.out.println(boolQueryBuilder);
    }
}
*/
